from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator


class Actor(models.Model):
    GENDER_CHOICES = (
        ((1, '男'), (2, '女'), (3, '其他'))
    )
    name = models.CharField(
        max_length=32, verbose_name='原姓名', unique=True, db_index=True
    )
    avatar = models.ImageField(
        upload_to='actors/portrait/', verbose_name='头像', blank=True, default='actors/portrait/default.png'
    )
    gender = models.IntegerField(
        verbose_name='性别', choices=GENDER_CHOICES, default=2, blank=True
    )
    birthday = models.DateField(
        verbose_name='生日', blank=True, null=True
    )
    country = models.ForeignKey(
        'Country',
        verbose_name='国家',
        on_delete=models.SET_NULL,
        null=True,
        blank=True
    )
    score = models.IntegerField(
        verbose_name='评分',
        validators=[MinValueValidator(0), MaxValueValidator(10)],
    )
    create_time = models.DateTimeField(
        verbose_name='创建时间', auto_now=True
    )
    update_time = models.DateTimeField(
        verbose_name='更新时间', auto_now_add=True
    )

    class Meta:
        db_table = 'cin_actor'
        verbose_name = '演员信息'
        verbose_name_plural = verbose_name
        indexes = [
            models.Index(fields=['name', 'score']),
            models.Index(fields=['birthday', 'country']),
        ]

    def __str__(self):
        return self.name

    @property
    def has_avatar(self):
        """检查是否有头像"""
        return bool(self.avatar) and bool(self.avatar.name)

    def get_avatar_url(self):
        return self.avatar.url if self.has_avatar else '/media/default/default.png'


class ActorDetails(models.Model):
    actor = models.OneToOneField(
        'Actor',
        verbose_name='演员',
        on_delete=models.CASCADE,
        related_name='details_actor'
    )
    roma = models.CharField(
        max_length=64,
        verbose_name='英文名',
        blank=True,
        null=True)

    alias = models.CharField(
        max_length=64,
        verbose_name='艺名',
        blank=True,
        null=True
    )
    height = models.SmallIntegerField(
        verbose_name='身高',
        help_text='单位 cm',
        blank=True,
        null=True
    )
    weight = models.SmallIntegerField(
        verbose_name='体重',
        help_text='单位 kg',
        blank=True,
        null=True
    )
    bust = models.SmallIntegerField(
        verbose_name='胸围',
        help_text='单位 cm',
        blank=True,
        null=True
    )
    hip = models.SmallIntegerField(
        verbose_name='臀围',
        help_text='单位 cm', blank=True, null=True)
    waist = models.SmallIntegerField(
        verbose_name='腰围', help_text='单位 cm', blank=True, null=True
    )
    cups = models.CharField(
        max_length=1, blank=True, null=True
    )
    ethnicity = models.CharField(
        max_length=64, verbose_name='民族', blank=True, null=True
    )
    birth_place = models.CharField(
        max_length=64, verbose_name='出生地', blank=True, null=True
    )
    blood_type = models.CharField(
        max_length=4, verbose_name='血型', blank=True, null=True
    )
    zodiac_sign = models.CharField(
        max_length=3, verbose_name='星座', blank=True, null=True
    )
    hobbies = models.CharField(
        max_length=128, verbose_name='兴趣爱好', blank=True, null=True
    )
    debut_at = models.DateField(
        verbose_name='首演时间', blank=True, null=True
    )

    profile = models.TextField(
        verbose_name='个人简介', blank=True, null=True
    )
    experience = models.JSONField(
        verbose_name='经历', blank=True, default=dict
    )

    create_time = models.DateTimeField(
        verbose_name='创建时间', auto_now=True
    )
    update_time = models.DateTimeField(
        verbose_name='更新时间', auto_now_add=True
    )

    class Meta:
        db_table = 'cin_actor_details'
        verbose_name = '演员详细信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.actor.name

    def get_experience(self):
        """获取结构化的经历数据"""
        # 确保 experience 字段存在且是列表
        if not isinstance(self.experience, dict):
            return []
        return sorted(
            (v for v in self.experience.values()
             if all(key in v for key in ['year', 'title', 'description'])),
            key=lambda x: x['year']
        )

    def set_experience(self, experience_data):
        """设置经历数据"""
        # 验证输入格式
        if not isinstance(experience_data, list):
            raise ValueError("经历数据必须是列表")

        # 验证每个项目
        for item in experience_data:
            if not isinstance(item, dict):
                raise ValueError("每个经历项目必须是字典")

            if not all(key in item for key in ['year', 'title', 'description']):
                raise ValueError("每个经历项目必须包含 'year', 'title', 'description' 字段")

        # 保存数据
        self.experience = experience_data
        self.save()

    def add_experience(self, year, title, description, **kwargs):
        """添加单个经历项"""
        # 确保 experience 字段是列表
        if not isinstance(self.experience, list):
            self.experience = []

        # 创建新项目
        new_item = {
            'year': year,
            'title': title,
            'description': description
        }

        # 添加可选字段
        for key, value in kwargs.items():
            if key not in ['year', 'title', 'description']:
                new_item[key] = value

        # 添加到经历列表
        self.experience.append(new_item)
        self.save()

    def to_dict(self, include_experience=True):
        """将模型转换为字典"""
        data = {
            'roma': self.roma,
            'alias': self.alias,
            'height': self.height,
            'weight': self.weight,
            'bust': self.bust,
            'hip': self.hip,
            'waist': self.waist,
            'cups': self.cups,
            'ethnicity': self.ethnicity,
            'birth_place': self.birth_place,
            'blood_type': self.blood_type,
            'zodiac_sign': self.zodiac_sign,
            'hobbies': self.hobbies,
            'debut_at': self.debut_at.strftime('%Y-%m-%d') if self.debut_at else None,
            'profile': self.profile,
        }

        if include_experience:
            data['experience'] = self.get_experience()

        return data


class Country(models.Model):
    country = models.CharField(max_length=32, verbose_name='中文名称')
    code = models.CharField(max_length=4, verbose_name='国家代码')

    class Meta:
        db_table = 'cin_country'
        verbose_name = '国家'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f'{self.country}-{self.code}'


class Company(models.Model):
    name = models.CharField(max_length=128, verbose_name='公司名称', unique=True, db_index=True)
    website = models.URLField(verbose_name='公司网址', blank=True, null=True)

    class Meta:
        db_table = 'cin_company'
        verbose_name = '媒体公司'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f'{self.name}-{self.website}'


class ActorToCompany:
    actor = models.ForeignKey(
        Actor,
        related_name='companies',
        on_delete=models.CASCADE
    )

    company = models.ForeignKey(
        Company, related_name='company_actor', on_delete=models.CASCADE
    )
    join_time = models.DateTimeField(verbose_name='加入时间', blank=True, null=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now_add=True)

    class Meta:
        db_table = 'cin_actor_to_company'
        verbose_name = '演员详细信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f'{self.actor.name}-{self.company.name}-{self.join_time}'
